﻿#include "ssRandomMaze.h"


namespace StarSeeker
{

ssRandomMaze::ssRandomMaze(void)
{
}

ssRandomMaze::~ssRandomMaze(void)
{
}

//建立迷宫
void ssRandomMaze::Bulid(u32 row, u32 column, coord_s in, coord_s out)
{
	m_numStack = 0;
	//设定尺寸
	m_row = SS_MIN(row,MAZE_ROW_MAX);
	m_column = SS_MIN(column, MAZE_COLUMN_MAX);
	m_cells.Init(m_row, column);
	//初始化
	for (u32 i=0; i<m_row; ++i)
	{
		for (u32 j=0; j<m_column; ++j)
		{
			if (i%2 || j%2)
			{
				m_cells(i,j) = 1;
			}
			else
			{
				m_cells(i,j) = 0;
			}
		}
	}
	m_cells(in.row, in.column) = 0;
	m_cells(out.row, out.column) = 0;
	//随机起点
	coord_s curr;
	curr.row = SS_STATIC_CAST(u32, SS_RAND->RandEven(0, m_row-1));
	curr.column = SS_STATIC_CAST(u32, SS_RAND->RandEven(0, m_column-1));
	coord_s next;
	coord_s wall;
	//PrintCells();
	do
	{
		m_cells(curr.row,curr.column) = 2;
		if (SelectNext(curr.row, curr.column, next))
		{
			m_stack[m_numStack++] = curr;
			//拆墙
			if (curr.row==next.row)
			{
				if (curr.column>next.column)
				{
					wall.column = next.column+1;
					wall.row = next.row;
				}
				else
				{
					wall.column = curr.column+1;
					wall.row = curr.row;
				}
				m_cells(wall.row,wall.column) = 0;
			}
			else if (curr.column==next.column)
			{
				if (curr.row>next.row)
				{
					wall.row = next.row+1;
					wall.column = next.column;
				}
				else
				{
					wall.row = curr.row+1;
					wall.column = curr.column;
				}
				m_cells(wall.row,wall.column) = 0;
			}
			curr = next;
		}
		else
		{
			u32 offset = SS_RAND->RandU32()%m_numStack;
			curr = m_stack[offset];
			m_stack[offset] = m_stack[m_numStack-1];
			--m_numStack;
		}
		//PrintCells();
	} while (m_numStack>0);
}

//选邻格
bool ssRandomMaze::SelectNext(u32 row, u32 column, coord_s &cd)
{
	coord_s next[4];
	memset(next,0,sizeof(next));
	int num = 0;
	//上
	if (row>=2 && m_cells(row-2,column)==0)
	{
		next[num].row = row-2;
		next[num].column = column;
		++num;
	}
	//下
	if (row+2<m_row && m_cells(row+2,column)==0)
	{
		next[num].row = row+2;
		next[num].column = column;
		++num;
	}
	//左
	if (column>=2 && m_cells(row,column-2)==0)
	{
		next[num].row = row;
		next[num].column = column-2;
		++num;
	}
	//右
	if (column+2<m_column && m_cells(row,column+2)==0)
	{
		next[num].row = row;
		next[num].column = column+2;
		++num;
	}
	if (num)
	{
		cd = next[SS_RAND->Rand()%num];
		return true;
	}
	else
	{
		return false;
	}
}

//查询坐标状态
i8 ssRandomMaze::GetCellState(u32 row, u32 column)
{
	if (row<m_row && column<m_column)
	{
		return m_cells(row,column)!=1?1:0;
	}
	return 2;
}

i8 ssRandomMaze::GetCellState( u32 offset )
{
	if (offset < m_row*m_column)
	{
		return m_cells(offset/m_column, offset%m_column)!=1?1:0;
	}
	return 2;
}

//随机一个有效坐标
ssRandomMaze::coord_s * ssRandomMaze::GetRandomPassed()
{
	if (m_numStack>0)
	{
		return &m_stack[--m_numStack];
	}
	return 0;
}

void ssRandomMaze::PrintCells()
{
	for (u32 i=0; i<m_row; ++i)
	{
		for (u32 j=0; j<m_column; ++j)
		{
			printf("%d", (int)m_cells(i,j));
		}
		printf("\n");
	}
	printf("\n");
}
//打乱有效坐标
void ssRandomMaze::RandomPassed()
{
	ShuffleArray(m_stack, m_numStack);
}
//统计有效坐标
void ssRandomMaze::StatisticPassed()
{
	//取出有效坐标
	m_numStack = 0;
	for (u32 i=0; i<m_row; ++i)
	{
		for (u32 j=0; j<m_column; ++j)
		{
			if (m_cells(i,j)!=1 && (i>0||j>0) && (i<m_row-1||j<m_column-1))
			{
				m_stack[m_numStack].row = i;
				m_stack[m_numStack].column = j;
				++m_numStack;
			}
		}
	}
}

}